# -*- coding: utf-8 -*-
# CreateDate : 2021/12/15 21:51
# Author     : 不肖生
# Github     :
# EditDate   :
# sourceProj : wuliu_news
# Description:
from datetime import datetime


class BaseItem:

    def __init__(self, **kwargs):
        for k, v in kwargs.items():
            setattr(self, k, v)

    def __str__(self):
        return str(self.__dict__)

    def __repr__(self):
        return str(self.__dict__)

    def get_value(self, field):
        """
        获取属性的值，如果该属性没有值，则返回类注解中该属性类型的空值，如果有多种类型，取第一种
        :param field:
        :return:
        """
        if field in self.__dict__:
            return self.__getattribute__(field)
        # 获取类注解中该属性的类型
        field_type = self.__annotations__.get(field) or self.__class__.__base__.__annotations__[field]
        # 如果有多种类型，取第一个
        if isinstance(field_type, list):
            field_type = field_type[0]
        # 返回空值
        return field_type()

    def set_value(self, field, value):
        """
        为属性赋值，如果该属性不在类注解中，抛出错误
        :param field:
        :param value:
        :return:
        """
        if field in self.__annotations__ or field in self.__class__.__base__.__annotations__:
            self.__setattr__(field, value)
        else:
            raise Exception(f"{field} is not defined in {self.__class__.__name__}.")

    def set_values(self, **kwargs):
        """
        根据传入的关键字参数，为对象赋值
        :param kwargs:
        :return:
        """
        for key, value in kwargs.items():
            self.set_value(key, value)

    def set_default(self, field):
        """
        给实例化对象 field 属性设置默认值，如果该属性已经有值，则跳过
        默认值为注解中相应类型的空值，如，注解为 int 类型的即为 0
        如果属性类型为 datetime 赋值当前时间
        :param field:
        :return:
        """
        # 属性已经有值，直接退出方法
        if field in self.__dict__:
            return
        attr_type = self.__annotations__[field]
        if attr_type == datetime:
            self.__setattr__(field, datetime.now())
        else:
            self.__setattr__(field, attr_type())

    def set_defaults(self, skip_time=True, except_field=None):
        """
        为实例化的对象的属性赋一个默认值，其值为类注解中该属性的类型的空值，因为 datetime 实例化要传参，可以选择跳过
        :param skip_time: 跳过 datetime 类型的属性
        :param except_field: 跳过该字段
        :return:
        """
        for k, v in self.__annotations__.items():
            if skip_time and (issubclass(v, datetime) or v == datetime):
                continue
            if except_field and v == except_field:
                continue
            self.set_default(k)
